package com.gcs.k8s01.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @Description TODO
 * @Author guosong
 * @Date 2023/11/27 10:21
 */
@Aspect
@Component
@Slf4j
@ConditionalOnProperty(name = "log.aspect.enable", havingValue = "true")
public class LogAspect {
    @Pointcut("(@annotation(SysLog))")
    private void logPoint(){
    }
    @Around("logPoint()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Object[] args = joinPoint.getArgs();
        Method method = signature.getMethod();
        SysLog sysLog = method.getAnnotation(SysLog.class);
        //获取reqData
        Object data = parseSpringEL(sysLog.reqData(), method, args);
        log.info("操作日志：{}，{}",sysLog.desc(),data);
        return joinPoint.proceed();

    }

    /**
     * 解析SpringEL表达式
     * @param springEl
     * @param method
     * @param args
     * @return
     * @throws Throwable
     */
    public Object parseSpringEL(String springEl, Method method,Object [] args) throws Throwable {
        if(null==springEl){
            return null;
        }
        //获取被拦截的方法参数名
        DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
        String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
        //创建上下文
        StandardEvaluationContext context = new StandardEvaluationContext();
        for (int i = 0; i< Objects.requireNonNull(parameterNames).length; i++){
            context.setVariable(parameterNames[i],args[i]);
        }
        //解析EL表达式
        ExpressionParser spelExpressionParser = new SpelExpressionParser();
        return spelExpressionParser.parseExpression(springEl).getValue(context);
    }




}
